package com.wxxymaker.controller;

import com.blade.kit.Base64;
import com.blade.kit.EncrypKit;
import com.wxxymaker.interceptor.annocation.AuthRequire;
import com.wxxymaker.model.entity.Shop;
import com.wxxymaker.model.entity.Stage;
import com.wxxymaker.model.entity.User;
import com.wxxymaker.service.MarkRecordService;
import com.wxxymaker.service.ShopService;
import com.wxxymaker.service.StageService;
import com.wxxymaker.service.UserService;
import com.wxxymaker.utils.ArrayUtils;
import com.wxxymaker.utils.Const;
import com.wxxymaker.utils.SimpleCache;
import com.wxxymaker.utils.auth.AuthUtil;
import com.wxxymaker.utils.web.ResponseWarp;
import com.wxxymaker.utils.web.ShopUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: Soft
 * @Date: 2018/5/6 16:13
 * @Desc: 用户处理器
 */
@Controller
@RequestMapping("/user")
public class UserHandler {
    private static Logger log = LoggerFactory.getLogger(UserHandler.class);

    private final UserService userService;

    private final ShopService shopService;

    private final StageService stageService;

    private final MarkRecordService markRecordService;

    @Autowired
    public UserHandler(MarkRecordService markRecordService, StageService stageService,
                       ShopService shopService, UserService userService) {
        this.markRecordService = markRecordService;
        this.stageService = stageService;
        this.shopService = shopService;
        this.userService = userService;

        // 默认系统初始化时禁止用户注册
        SimpleCache.set(Const.ALLOW_USER, false);
    }

    /**
     * 用户注册开关
     * @param can 大于0允许 小于关闭 管理员权限
     */
    @PostMapping("/can_reg/{can}")
    @ResponseBody
    public void canReg(@PathVariable Integer can) {
        if (can > 0) {
            SimpleCache.set(Const.ALLOW_USER, true);
        } else {
            SimpleCache.set(Const.ALLOW_USER, false);
        }
    }

    /**
     * 用户登录
     * @param user     要登录的用户
     * @param session  页面session
     * @param response 响应
     */
    @PostMapping("/login")
    @ResponseBody
    public ResponseWarp login_(User user, HttpSession session,
                               HttpServletResponse response) {
        if (userService.checkUser(user)) {
            String base64Md5 = AuthUtil.toBase64Md5(user);
            if ("true".equals(user.getRemember())) {
                Cookie cookie = new Cookie(Const.U_COOKIE, base64Md5);
                cookie.setMaxAge(3600*24*10); // 保存十天
                response.addCookie(cookie);
            }
            session.setAttribute(Const.U_SESSION, base64Md5);
            return ResponseWarp.ok("登录成功！");
        }
        return  ResponseWarp.error("登录失败！");
    }

    /**
     * 用户注册
     * @param user 要注册的用户
     */
    @PostMapping("/register")
    @ResponseBody
    public ResponseWarp register_(User user) {
        if ((boolean) SimpleCache.get(Const.ALLOW_USER)) {
            if (userService.getByUsername(user.getUsername()) == null) {
                if (userService.add(user) != null) {
                    return ResponseWarp.ok("注册成功！");
                }
            }
            return ResponseWarp.error("用户名已存在！");
        } else {
            return ResponseWarp.error("用户注册功能已被关闭！");
        }
    }

    /**
     * 用户注销登录
     */
    @PostMapping("/logout")
    @ResponseBody
    public ResponseWarp logout(HttpSession session,
                               HttpServletResponse response) {
        Cookie cookie = new Cookie(Const.U_COOKIE, "");
        cookie.setMaxAge(0);
        session.removeAttribute(Const.U_SESSION);
        session.removeAttribute("user"); // 临时添加
        response.addCookie(cookie);
        return ResponseWarp.ok("注销成功！");
    }

    /**
     * 验证用户名是否占用
     * @param username 需要验证的用户名
     */
    @PostMapping("/check_username")
    @ResponseBody
    public ResponseWarp checkUsername(@RequestParam String username) {
        if (userService.getByUsername(username) == null) {
            return ResponseWarp.ok("用户名未被占用，合法！");
        }
        return ResponseWarp.error("用户名已被占用，请替换！");
    }

    /**
     * 找回密码
     * 需要用户权限
     * @param user 需要找回密码的用户，包括用户名，新密码和正确的电话号码
     */
    @PostMapping("/get_back")
    @ResponseBody
    public ResponseWarp getBack_(User user) {
        UserService.BackStatus back = userService.getBack(user);
        if (back.isSuccess()) {
            return ResponseWarp.ok(back.getMsg());
        }
        return ResponseWarp.error(back.getMsg());
    }

    /**
     * 删除用户接口
     * @param id 要删除的用户id
     */
    @PostMapping("/delete/{id}")
    @ResponseBody
    public ResponseWarp delete(@PathVariable Integer id) {
        User user = userService.delete(id);
        if (null != user) {
            return ResponseWarp.ok(user);
        }
        return ResponseWarp.error("删除失败！");
    }

    /**
     * 修改个人信息
     * 需要用户权限
     * @param user 要修改信息的用户
     */
    @PostMapping("/change")
    @ResponseBody
    public ResponseWarp change_(User user) {
        if (null != user && user.getId() > 0) {
            if (!StringUtils.isEmpty(user.getPassword())) {
                user.setPassword(EncrypKit.md5(user.getPassword()));
            }
            if (userService.change(user)) {
                return ResponseWarp.ok("修改成功！");
            }
        }
        return ResponseWarp.error("修改失败！");
    }

    /**
     * 根据用户id获取用户
     * 需要管理员权限，无需用户权限
     * @param id 用户id
     */
    @PostMapping("/byid/{id}")
    @ResponseBody
    public ResponseWarp get(@PathVariable Integer id) {
        User one = userService.getOne(id);
        if (null != one) {
            return ResponseWarp.ok(one);
        }
        return ResponseWarp.error("获取用户失败！");
    }

    /**
     * 根据用户名对用户进行模糊查询
     * @param name 用户真名
     */
    @AuthRequire
    @PostMapping("/byname/{name}")
    @ResponseBody
    public ResponseWarp byName(@PathVariable String name) {
        List<User> users = userService.getByLikeName(name);
        if (null != users) {
            return ResponseWarp.ok(users);
        }
        return ResponseWarp.error("获取用户(" + name + ")信息失败！");
    }

    /**
     * 用户分页查询
     */
    @PostMapping("/page/{pageNo}")
    @ResponseBody
    public ResponseWarp page(@PathVariable Integer pageNo) {

        return ResponseWarp.error("获取失败！");
    }

    /**
     * 用户打分界面
     * 包括阶段类型和用户类型的全部判断后才显示对应的被打分项　stageType userType
     */
    @GetMapping("/markView/{stageId}")
    public String markView(ModelMap map, @PathVariable Integer stageId,
                           @RequestParam String limit, @RequestParam(defaultValue = "") String ids,
                           HttpServletRequest request) {
        String QRLimit = (String) SimpleCache.get(Const.QRLIMIT);
        if (stageId != null && QRLimit != null && QRLimit.equals(limit)) {
            Stage   stage = stageService.getOne(stageId);
            Integer post  = ((User) request.getAttribute("user")).getPost();  // 获取在拦截器中存放的用户的职位

            try {
                Integer[] targetIds = ArrayUtils.fromHexString(ids);
                Integer[] shopsId   = ShopUtil.getShopIdsArr(stage.getShopIds());
                if (targetIds == null || Arrays.asList(shopsId).containsAll(Arrays.asList(targetIds))) { // 被打分项必须是阶段中存在的
                    // 根据指定阶段和用户类型为打分用户提供指定的公司来打分，如：教师可以打教师食堂
                    Page<Shop> shops  = shopService.page(1, 10000,
                            targetIds != null ? targetIds : shopsId,
                            ShopUtil.getTypeByUser(post));
                    map.addAttribute("pages", shops);
                    map.addAttribute("limit", limit);
                    map.addAttribute("stageId", stage.getId());
                    return "/markView";
                }
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        }
        map.addAttribute("msg", "您访问的界面不见了！");
        return "/error/404";
    }

    /**
     * 用户主页
     * 带入综合评分最高的食堂和物业信息
     */
    @GetMapping({"", "/home"})
    public String home(ModelMap map, HttpServletRequest request) {
        User user = (User) request.getAttribute("user");
        Shop bestSt = null;
        if (user.getPost() == User.PostDim.STU) {
            bestSt = shopService.getBest(Shop.TypeDim.STUST);
        }
        Shop bestWy = shopService.getBest(Shop.TypeDim.WUYE);
        map.put("bestWy", bestWy);
        map.put("bestSt", bestSt);
        return "/home";
    }

    /**
     * 用户个人记录界面
     * 带入记录分页信息和所有公司信息
     */
    @GetMapping("/record")
    public String record(ModelMap map, @RequestParam(defaultValue = "1") Integer pageNo,
                         HttpServletRequest request) {
        return "/error/404";
        /*User user = (User) request.getAttribute("user");
        Map<String, Object> query = new HashMap<>();
        query.put("user_id", user.getId()); // 确定用户信息，只能获取当前用户的信息
        map.put("pages", markRecordService.page(query, pageNo));
        map.put("stages", stageService.findAll());  // 暂时这样获取，后面可以修改为获取和该用户相关的阶段
        map.put("shops", shopService.findByType(ShopUtil.getTypeByUser(user.getPost())));
        return "/record";*/
    }

    /**
     * 用户公司排名界面
     */
    @Deprecated
    @GetMapping("/rank")
    public String mark(ModelMap map) {
        return "/error/404";
        /*Page<Shop> page = shopService.page(1, Const.pageSize);
        map.put("pages", page);
        return "/rank";*/
    }

    /**
     * 登录界面
     * @param prev 记录上一个页面base64加密的url
     */
    @GetMapping("/login")
    public String login(@RequestParam(defaultValue = "") String prev, ModelMap map) {
        map.put("prev", new String(Base64.decode(prev, Base64.NO_WRAP)));
        return "/login";
    }

    /**
     * 用户注册界面
     */
    @GetMapping("/register")
    public String register(ModelMap map) {
        map.put("CanReg", SimpleCache.get(Const.ALLOW_USER));
        return "/register";
    }

    /**
     * 关于界面
     */
    @GetMapping("/about")
    public String about() {
        return "/about";
    }

    /**
     * 修改个人信息界面
     */
    @GetMapping("/change")
    public String change() {
        return "/change";
    }

    /**
     * 修改密码界面
     */
    @GetMapping("/change_mm")
    public String changeMm() {
        return "/change_mm";
    }

    /**
     * 密码找回界面
     */
    @GetMapping("/get_back")
    public String getBack() {
        return "/get_back";
    }

    /**
     * 帮助
     */
    @GetMapping("/help")
    public String help() {
        return "/help";
    }
}
